package com.gateway.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Collections;

/**
 * 验证token
 */
@Component
@Slf4j
public class OAuthFilter extends ZuulFilter {

    @Autowired
    private RestTemplate restTemplate;


    /**
     * 提供四种过滤类型，pre-请求前，post-请求之后,error-出错之后,route-控制路由
     * @return
     */
    public String filterType() {
        return "pre";
    }

    /**
     * 过滤器执行顺序
     * @return
     */
    public int filterOrder() {
        return 1;
    }

    /**
     * 过滤器是否起作用，true，启用过滤器
     * @return
     */
    public boolean shouldFilter() {
        return true;
    }

    /**
     * 要写的业务逻辑
     * @return
     * @throws ZuulException
     */
    public Object run() throws ZuulException {
        log.info("oauth start");
        RequestContext requestContext=RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();

        //请求开头是不是以token开头的，发往认证服务器的请求不用验证
        if(StringUtils.startsWith(request.getRequestURI(),"/token")){
            return null;
        }

        String requestHeader=request.getHeader("Authorization");

        if(StringUtils.isBlank(requestHeader)){
            return null;
        }

        if(!StringUtils.startsWithIgnoreCase(requestHeader,"bearer ")){
            return null;
        }

        try{
            TokenInfo tokenInfo=getTokenInfo(requestHeader);
            request.setAttribute("tokenInfo",tokenInfo);
        }catch(Exception e){
            log.info("get token info fail:",e);
        }



        return null;
    }

    private TokenInfo getTokenInfo(String requestHeader) {
        String token=StringUtils.substringAfter(requestHeader,"bearer ");
        String oauthServiceUrl="http://localhost:8085/oauth/check_token";
        HttpHeaders httpHeaders=new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        httpHeaders.setBasicAuth("gateway","123456");

        //只能用这个map，用hashmap什么的，报错
        MultiValueMap<String,String> params=new LinkedMultiValueMap<String, String>();
        params.add("token", token);

        HttpEntity<MultiValueMap<String,String>> entity=new HttpEntity<MultiValueMap<String, String>>(params,httpHeaders);

        ResponseEntity<TokenInfo> response=restTemplate.exchange(oauthServiceUrl, HttpMethod.POST,entity,TokenInfo.class);

        log.info("token info:{}",response.getBody().toString());
        return response.getBody();
    }
}
